/**
  ******************************************************************************
  * @file    main.c
  * @author  AE Team
  * @version 1.0.3
  * @date    2024-05-28
  * @brief   本样例演示I2CMaster通过查询方式读写EEPROM(24Cxx)
  *          I2C.SCL(PB05) -> EEPROM.SCL
  *          I2C.SDA(PB06) -> EEPROM.SDA
  *
  *          注意：需要在SCL/SDA线上外接上拉电阻
  *
  * @note    硬件平台：SYM32L010_StartKit_V1.0
  *          接线说明：断开J18、J20
  *                    短接J14、J15、J16、J28
  *
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2024 SIYIMicro.
  * All rights reserved.</center></h2>
  *
  *
  ******************************************************************************
  */


/******************************************************************************/
/* Include files                                                              */
/******************************************************************************/
#include "main.h"
#include "sym32l010_hal_sysctrl.h"
#include "sym32l010_hal_systick.h"
#include "sym32l010_hal_gpio.h"
#include "sym32l010_hal_i2c.h"
#include "sym32l010_startkit_board.h"


/******************************************************************************/
/* Local pre-processor symbols/macros ('#define')                             */
/******************************************************************************/

/******************************************************************************/
/* Global variable definitions (declared in header file with 'extern')        */
/******************************************************************************/
I2C_HandleTypeDef hi2c1;
uint8_t DeviceAddr = 0xA0;
uint8_t TxBuf[10];
uint8_t RxBuf[10];

/******************************************************************************/
/* Local type definitions ('typedef')                                         */
/******************************************************************************/

/******************************************************************************/
/* Local function prototypes ('static')                                       */
/******************************************************************************/
static void I2C1_Init(void);

/******************************************************************************/
/* Local variable definitions ('static')                                      */
/******************************************************************************/

/******************************************************************************/
/* Local pre-processor symbols/macros ('#define')                             */
/******************************************************************************/

/******************************************************************************/
/* Function implementation - global ('extern') and local ('static')           */
/******************************************************************************/


/*******************************************************************************
 ** \brief  Main function of project
 **
 ** \return uint32_t return value, if needed
 **
 **
 ******************************************************************************/
int32_t main(void)
{
    // 初始化系统时钟
    HAL_SysCtrl_HSI_SetDiv(HSIOSC_TO_HSI24MHZ);

    // 初始化SysTick
    HAL_InitTick(24000000);

    // 初始化板载LED
    Bsp_Led_Init();

    // 初始化I2C1
    I2C1_Init();

/*
    // 调用驱动库实现读写EEPROM (详细步骤方式)
    while (1)
    {
        //--------------------------------------------------------
        // 以下准备待写入的数据
        TxBuf[0] = 0x00;
        for (uint8_t i = 1; i <= 8; i++)
        {
            TxBuf[i] += 37 + i;
        }

        HAL_StatusTypeDef tmp8 = HAL_OK;

        //--------------------------------------------------------
        // 以下为写EEPROM数据流程
        tmp8 = HAL_I2C_Master_SendStart(hi2c1.Instance);              // 发送START信号
        if (tmp8 == HAL_OK)
        {
            tmp8 = HAL_I2C_Master_SendByte(hi2c1.Instance, DeviceAddr); // 发送设备地址（写模式）
        }
        if (tmp8 == HAL_OK)
        {
            tmp8 = HAL_I2C_Master_SendByte(hi2c1.Instance, TxBuf[0]); // 发送需要写入的EEPROM的地址
        }
        for (uint8_t i = 1; i <= 8; i++)                              // 发送8字节数据
        {
            if (tmp8 == HAL_OK)
            {
                tmp8 = HAL_I2C_Master_SendByte(hi2c1.Instance, TxBuf[i]);
            }
        }
        HAL_I2C_Master_SendStop(hi2c1.Instance);                      // 发送停止信号

        //--------------------------------------------------------
        // 等待EE完成擦写过程
        while (HAL_I2C_Master_IsDeviceReady(&hi2c1, DeviceAddr, 3) != HAL_OK)
        {
            HAL_Delay(1);
        }

        //--------------------------------------------------------
        // 以下为读出EEPROM数据流程
        if (tmp8 == HAL_OK)
        {
            tmp8 = HAL_I2C_Master_SendStart(hi2c1.Instance);          // 发送START信号
        }
        if (tmp8 == HAL_OK)
        {
            tmp8 = HAL_I2C_Master_SendByte(hi2c1.Instance, DeviceAddr); // 发送设备地址（写模式）
        }
        if (tmp8 == HAL_OK)
        {
            tmp8 = HAL_I2C_Master_SendByte(hi2c1.Instance, TxBuf[0]); // 发送需要读取的EEPROM的地址
        }
        if (tmp8 == HAL_OK)
        {
            tmp8 = HAL_I2C_Master_SendReStart(hi2c1.Instance);        // 发送ReSTART信号
        }
        if (tmp8 == HAL_OK)
        {
            tmp8 = HAL_I2C_Master_SendByte(hi2c1.Instance, DeviceAddr | 0x01); // 发送设备地址（读模式）
        }
        if (tmp8 == HAL_OK)
        {
            for (uint8_t i = 1; i <= 8; i++)                          // 读取8字节数据
            {
                RxBuf[i] = HAL_I2C_Master_RecvByte(hi2c1.Instance, (i == 8) ? I2C_RESPONSE_NAK : I2C_RESPONSE_ACK);
            }
        }
        HAL_I2C_Master_SendStop(hi2c1.Instance);                      // 发送停止信号

        if (tmp8 != HAL_OK)                                           // I2C出错，需读取I2C_STAT以查证原因
        {
            while (1);
        }

        //--------------------------------------------------------
        // 以下比较读出与写入的数据是否相同
        for (uint8_t i = 1; i <= 8; i++)
        {
            if (TxBuf[i] != RxBuf[i])                                 // 写入与读出的数据不一致
            {
                while (1);
            }
        }

        //--------------------------------------------------------
        HAL_Delay(100);
        BSP_LED_TOG();
    }
*/


    // 调用驱动库实现读写EEPROM (驱动库封装方式)
    while (1)
    {
        //--------------------------------------------------------
        // 以下准备待写入的数据
        TxBuf[0] = 0x00;                                              // Set MemAddr
        for (uint32_t i = 1; i <= 8; i++)                             // Set Data
        {
            TxBuf[i] += 37 + i;
        }

        HAL_StatusTypeDef tmp8 = HAL_OK;

        //--------------------------------------------------------
        // 以下为写数据流程
        tmp8 = HAL_I2C_Master_Transmit(&hi2c1, DeviceAddr, TxBuf, 9, 100); // 向EE的0x00地址写入8字节数据

        //--------------------------------------------------------
        // 等待EE完成擦写过程
        while (HAL_I2C_Master_IsDeviceReady(&hi2c1, DeviceAddr, 3, 100) != HAL_OK)
        {
            HAL_Delay(1);
        }

        //--------------------------------------------------------
        // 以下为读出数据流程
        if (tmp8 == HAL_OK)
        {
            hi2c1.XferDone = I2C_XFERDONE_NONE;                       // 设置传输参数：发送完成后不停止
            tmp8 = HAL_I2C_Master_Transmit(&hi2c1, DeviceAddr, TxBuf, 1, 100); // 更改EE地址指针
            hi2c1.XferDone = I2C_XFERDONE_STOP;                       // 设置传输参数：发送完成后停止
        }
        if (tmp8 == HAL_OK)
        {
            tmp8 = HAL_I2C_Master_Receive(&hi2c1, DeviceAddr, &RxBuf[1], 8, 100); // 读出8个字节
        }
        if (tmp8 != HAL_OK)                                           // I2C出错，需读取I2C_STAT以查证原因
        {
            while (1);
        }

        //--------------------------------------------------------
        // 以下比较读出与写入的数据是否相同
        for (uint32_t i = 1; i <= 8; i++)
        {
            if (TxBuf[i] != RxBuf[i])                                 // 写入与读出的数据不一致
            {
                while (1);
            }
        }

        //--------------------------------------------------------
        HAL_Delay(100);
        BSP_LED_TOG();
    }


}


/*******************************************************************************
 * @brief  I2C1 初始化
 * @param  None
 * @retval None
 */
static void I2C1_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    MemClr(&GPIO_InitStruct, sizeof(GPIO_InitStruct));

    // 使能外设时钟
    HAL_SYSCTRL_I2C1_CLK_ENABLE();
    HAL_SYSCTRL_GPIOB_CLK_ENABLE();

    // Config PB06/PB05 as SCL/SDA
    AFx_I2C1SCL_PB06();
    AFx_I2C1SDA_PB05();
    GPIO_InitStruct.Pins = GPIO_PIN_5 | GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
    GPIO_InitStruct.Pull = GPIO_PULL_UP;
    HAL_GPIO_Init(SYM_GPIOB, &GPIO_InitStruct);

    // 配置I2C1
    MemClr(&hi2c1, sizeof(hi2c1));

    hi2c1.Instance      = SYM_I2C1;
    hi2c1.Init.PclkFreq = 24000000;                                   // PCLK = 24MHz
    hi2c1.Init.SclFreq  = 1000000;                                    // SCL = 1MHz
    hi2c1.Init.WorkMode = I2C_WORKMODE_MASTER;
    HAL_I2C_Init(&hi2c1);
}


/*******************************************************************************
 ** EOF (not truncated)
 ******************************************************************************/
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* USER CODE BEGIN */
    /* User can add his own implementation to report the file name and line number,
       tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* USER CODE END */
}
#endif /* USE_FULL_ASSERT */


/************************ (C) COPYRIGHT SIYIMicro *****END OF FILE*************/
